package org.example.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.example.pojo.DRepair;
import org.example.pojo.DRepairContent;
import org.example.pojo.DStaff;
import org.example.pojo.select.DRepairSelect;
import org.example.service.DRepairService;
import org.example.mapper.DRepairMapper;
import org.example.utils.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;

/**
* @author chenhongkai
* @description 针对表【d_repair(报修表)】的数据库操作Service实现
* @createDate 2024-05-25 16:06:27
*/
@Service
public class DRepairServiceImpl extends ServiceImpl<DRepairMapper, DRepair>
    implements DRepairService{

    @Autowired
    private DRepairMapper dRepairMapper;

    @Override
    public Result<Map> SelectAllRepairs(DRepairSelect dRepairSelect){
        //分页查询
        Page<DRepair> page = new Page<>(dRepairSelect.getCurrentPage(),dRepairSelect.getPageSize());
        page.setSearchCount(false);
        Integer selectAllRepairs = dRepairMapper.SelectAllRepairsTotal(dRepairSelect);
        page.setTotal(selectAllRepairs);
        IPage<Map> mapIPage = dRepairMapper.SelectAllRepairs(page,dRepairSelect);

        Map repairMap = new HashMap<>();
        repairMap.put("pageSize",mapIPage.getSize());
        repairMap.put("pageTotal",mapIPage.getTotal());
        repairMap.put("repairData",mapIPage.getRecords());

        return Result.ok(repairMap);
    }

    @Override
    public Result<DRepair> UpdateStatus(DRepair dRepair) {
        dRepair.setUpdateDate(new Date());
        if(dRepair.getRepairStatus() == 3){
            dRepair.setCompleteDate(new Date());
        }
        int row = dRepairMapper.updateById(dRepair);
        if(row == 0) return Result.error("修改报修状态失败");
        return Result.ok(null);
    }

    @Override
    public List<String> getRepairType() {
        return dRepairMapper.getRepairType();
    }

//    @Override
//    public Result<DRepair> UpdateRepairman(DRepair dRepair) {
//        if(dRepair.getRmid() != null) dRepair.setRepairStatus(1);
//        dRepair.setUpdateDate(new Date());
//        int row = dRepairMapper.updateById(dRepair);
//        if(row == 0) return Result.error("指定维修人失败");
//        return Result.ok(null);
//    }


    @Value("${app.nowRid}")
    private Integer nowRid;

    @Override
    public Result<String> Insert(DRepair dRepair) {

        LocalDateTime currentTime = LocalDateTime.now();

        //插入表的时间
        String timeStrSS = String.valueOf(currentTime.getYear())
                + String.format("%02d",currentTime.getMonthValue())
                + String.format("%02d",currentTime.getDayOfMonth())
                + String.format("%02d",currentTime.getHour())
                + String.format("%02d",currentTime.getMinute())
                + String.format("%02d",currentTime.getSecond());

        //当日日期
        String timeStrDD = String.valueOf(currentTime.getYear())
                + String.format("%02d",currentTime.getMonthValue())
                + String.format("%02d",currentTime.getDayOfMonth());

//        System.out.println("当前时间 (timeStrSS): " + timeStrSS);
//        System.out.println("当前时间 (timeStrDD): " + timeStrDD);

        LambdaQueryWrapper<DRepair> selectRepairRid = new LambdaQueryWrapper<>();
        selectRepairRid.like(DRepair::getRid,timeStrDD+"%")
                .orderByDesc(DRepair::getRid);
        List<DRepair> dRepairSelects = dRepairMapper.selectList(selectRepairRid);

        //判断设置报修单号Rid
        if(dRepairSelects.isEmpty()){
            dRepair.setRid(timeStrSS + "001");
        }else{
            // 获取字符串的长度
            int length = dRepairSelects.get(0).getRid().length();
            String lastThreeChars = dRepairSelects.get(0).getRid().substring(length - 3);
            int ridCount = Integer.parseInt(lastThreeChars);
            //格式化序号
            dRepair.setRid(timeStrSS + String.format("%03d", ++ridCount));
        }

        dRepair.setRepairStatus(1);
        String rid = dRepair.getRid();

        dRepairMapper.insertRepair(dRepair);

        return Result.ok(rid);
    }

    @Value("${app.urlImage}")
    private String urlImage;
    @Override
    public String uploadImage(MultipartFile file,String imageNo) throws IOException {
        if (file.isEmpty()) {
            return "上传失败，文件为空";
        }

        System.out.println("file = " + file);
        System.out.println("file.getInputStream() = " + file.getInputStream());
        // 读取原图片信息
        Image srcImg = ImageIO.read(file.getInputStream());

        System.out.println("srcImg = " + srcImg);

        int srcImgWidth = srcImg.getWidth(null);
        int srcImgHeight = srcImg.getHeight(null);

        // 加水印
        BufferedImage bufImg = new BufferedImage(srcImgWidth,
                srcImgHeight,
                BufferedImage.TYPE_INT_RGB);
        //获取 Graphics2D 对象
        Graphics2D g = bufImg.createGraphics();

        //设置绘图区域
        g.drawImage(srcImg, 0, 0, srcImgWidth, srcImgHeight, null);
        //设置字体
        int baseFontSize = 20; // 基础字体大小，可以根据需要调整
        int scalableFontSize = (int) (srcImgWidth * 0.05); // 假设字体大小是图片宽度的5%
        int finalFontSize = Math.min(scalableFontSize, baseFontSize * 5); // 限制最大字体大小，避免过大
        Font font = new Font("宋体", Font.PLAIN, finalFontSize);
        // 根据图片的背景设置水印颜色
        g.setColor(Color.gray);
        g.setFont(font);

        //设置水印文字
        String shuiying_date = LocalDateTime.now().getYear()+"-"+LocalDateTime.now().getMonthValue()+"-"+LocalDateTime.now().getDayOfMonth()
                +" "+ LocalDateTime.now().getHour() + ":" + LocalDateTime.now().getMinute() + ":" + LocalDateTime.now().getSecond();
        int len1 = g.getFontMetrics(g.getFont()).charsWidth(shuiying_date.toCharArray(), 0, shuiying_date.length());
        int x1 = srcImgWidth - len1 - 10;
        int y1 = srcImgHeight - 20;
        g.drawString(shuiying_date, x1, y1);

        String shuiying_rid = imageNo.substring(0,17);
        int len2 = g.getFontMetrics(g.getFont()).charsWidth(shuiying_rid.toCharArray(), 0, shuiying_rid.length());
        int x2 = srcImgWidth - len2 - 10;
        int y2 = srcImgHeight - finalFontSize - 20;
        g.drawString(shuiying_rid, x2, y2);

        String shuiying_tag = "奥飞宿舍报修";
        int len3 = g.getFontMetrics(g.getFont()).charsWidth(shuiying_tag.toCharArray(), 0, shuiying_tag.length());
        int x3 = srcImgWidth - len3 - 10;
        int y3 = srcImgHeight - (finalFontSize * 2) - 20;
        g.drawString(shuiying_tag, x3, y3);
        g.dispose();

        // 图片保存路径
        String fileSrc = urlImage + imageNo.substring(0,17) + "/" + imageNo + ".jpg";
        File waterFile = new File(urlImage  + imageNo.substring(0,17) );
        if(!waterFile.exists()) waterFile.mkdirs();
        FileOutputStream outImgStream = new FileOutputStream(fileSrc);

        // 输出图片
        ImageIO.write(bufImg, "png", outImgStream);
        outImgStream.flush();
        outImgStream.close();

        return fileSrc;


//        File dest = null;
//        String finalFilePath = null;
//        do
//        {
//            finalFilePath = urlImage + imageNo + ".jpg";
//            dest = new File(finalFilePath);
//        }
//        while(dest.exists());
//
//        try {
//            file.transferTo(dest);
//            return "上传成功： " + dest.getAbsolutePath();
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//
//        return "上传失败";
    }


    @Override
    public List<String> getApartmentAllId() {
        List<String>  apartmentIds =dRepairMapper.getApartmentAllId();
        return apartmentIds;
    }

    @Override
    public  Result<DStaff> selectStaffNoByNo(String staffId) {
        DStaff staff = dRepairMapper.selectStaffNoByNo(staffId);
        return Result.ok(staff);
    }

    @Override
    public Result<List<DRepair>> selectDeviceUid(String uid) {
        List<DRepair> repairs = dRepairMapper.selectDeviceUid(uid);
        return Result.ok(repairs);
    }

    @Override
    public Result<Map> getRepairStatistic(String month) {

        Map staticMap = new HashMap();
        DRepairSelect dRepairSelect = new DRepairSelect();


        // 解析输入的字符串
        DateTimeFormatter inputFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
        LocalDate firstDayOfMonth = LocalDate.parse(month, inputFormatter).withDayOfMonth(1);
        LocalDate lastDayOfMonth = firstDayOfMonth.with(java.time.temporal.TemporalAdjusters.lastDayOfMonth());

        dRepairSelect.setStartDate(String.valueOf(firstDayOfMonth));
        dRepairSelect.setEndDate(String.valueOf(lastDayOfMonth));



        //查询正在处理的报修单数量
        dRepairSelect.setRepairStatus(1);
        Integer repair_process = dRepairMapper.SelectAllRepairsTotal(dRepairSelect);
        //查询已完成的报修单数量
        dRepairSelect.setRepairStatus(3);
        Integer repair_complete = dRepairMapper.SelectAllRepairsTotal(dRepairSelect);
        //查询已取消的报修单数量
        dRepairSelect.setRepairStatus(-1);
        Integer repair_cancel = dRepairMapper.SelectAllRepairsTotal(dRepairSelect);

        staticMap.put("repairProcess", repair_process);
        staticMap.put("repairComplete", repair_complete);
        staticMap.put("repairCancel", repair_cancel);
        staticMap.put("repairTotal", repair_process+repair_complete+repair_cancel);

        Map repairTypeMap = new HashMap();
        dRepairSelect.setRepairStatus(null);
        List<String> repairTypes = dRepairMapper.getRepairType();
        for(String repairType : repairTypes){
            dRepairSelect.setRepairType(repairType);
            repairTypeMap.put(repairType,dRepairMapper.SelectAllRepairsTotal(dRepairSelect));
        }
        staticMap.put("repairType",repairTypeMap);

        return Result.ok(staticMap);
    }

    @Override
    public Result<DRepair> UpdateRepairman(DRepair dRepair) {
        int row = dRepairMapper.updateById(dRepair);
        if(row == 0 ) return Result.error("指定报修人失败");
        return Result.ok(null);
    }

    @Override
    public Result<Integer> repairCount() {
        DRepairSelect dRepairSelect = new DRepairSelect();
        dRepairSelect.setRepairStatus(1);
        Integer i = dRepairMapper.SelectAllRepairsTotal(dRepairSelect);
        return Result.ok(i);
    }

    @Override
    public Result<List<DRepairContent>> selectRepairContent(DRepairContent dRepairContent) {
        List<DRepairContent> dRepairContentList = dRepairMapper.selectRepairContent(dRepairContent.getRid());
        return Result.ok(dRepairContentList);
    }

    @Override
    @Transactional
    public Result<String> updateRepairContent(DRepairContent dRepairContent) {
        //原有数据
        List<DRepairContent> repairContents = dRepairContent.getRepairContents();
        //更新数据
        List<DRepairContent> dRepairContentList = dRepairMapper.selectRepairContent(dRepairContent.getRid());


        // 找出相同的对象
        Set<DRepairContent> commonSet = new HashSet<>(repairContents);
        commonSet.retainAll(dRepairContentList);
        List<DRepairContent> commonList = new ArrayList<>(commonSet);

        // 找出互不相同的对象（包括在repairContents中但不在dRepairContentList中的，以及相反的情况）
        Set<DRepairContent> uniqueSet = new HashSet<>(repairContents);
        uniqueSet.addAll(dRepairContentList);
        Set<DRepairContent> onlyInRepairContents = new HashSet<>(repairContents);
        onlyInRepairContents.removeAll(dRepairContentList);
        Set<DRepairContent> onlyInDRepairContentList = new HashSet<>(dRepairContentList);
        onlyInDRepairContentList.removeAll(repairContents);

        // 互不相同的对象列表（可以合并或分别处理）
        List<DRepairContent> uniqueInRepairContents = new ArrayList<>(onlyInRepairContents);
        List<DRepairContent> uniqueInDRepairContentList = new ArrayList<>(onlyInDRepairContentList);

        //相同的更新
        for(DRepairContent obj : commonList){
//            System.out.println("obj1 = " + obj);
            dRepairMapper.updateRepairContent(obj);
        }
        //删除
        for(DRepairContent obj : uniqueInDRepairContentList){
//            System.out.println("obj2 = " + obj);
            dRepairMapper.deleteRepairContent(obj.getRcid());
        }
        //新增
        for(DRepairContent obj : uniqueInRepairContents){
//            System.out.println("obj3 = " + obj);
            dRepairMapper.insertRepairContent(obj);
        }

//        //先全部删除
//        dRepairMapper.deleteAllRepairContent(dRepairContent.getRid());
//        for(DRepairContent repairContent : dRepairContent.getRepairContents()){
//            int rowInsert = dRepairMapper.insertRepairContent(repairContent);
//            //新增失败报错
//            if(rowInsert == 0)
//                return Result.error("维修内容更新失败");
//        }
        return Result.ok("维修内容更新成功");
    }


}




